﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPC.Communication.Framework.BasicFramework;
using IPC.Communication.Framework.Core;

namespace IPC.Communication.Framework.Profinet.Delta
{
    public class DeltaHelper
    {
        public static OperateResult<string> PraseDeltaDvpAddress(string address, byte modbusCode)
        {
            try
            {
                string str = string.Empty;
                OperateResult<int> operateResult = HslHelper.ExtractParameter(ref address, "s");
                if (operateResult.IsSuccess)
                {
                    str = String.Format("s={0};", operateResult.Content);
                }
                if (modbusCode == 1 || modbusCode == 15 || modbusCode == 5)
                {
                    if (address.StartsWith("S") || address.StartsWith("s"))
                    {
                        return OperateResult.CreateSuccessResult(str + Convert.ToInt32(address.Substring(1)).ToString());
                    }
                    if (address.StartsWith("X") || address.StartsWith("x"))
                    {
                        return OperateResult.CreateSuccessResult(str + "x=2;" + (Convert.ToInt32(address.Substring(1), 8) + 1024).ToString());
                    }
                    if (address.StartsWith("Y") || address.StartsWith("y"))
                    {
                        return OperateResult.CreateSuccessResult(str + (Convert.ToInt32(address.Substring(1), 8) + 1280).ToString());
                    }
                    if (address.StartsWith("T") || address.StartsWith("t"))
                    {
                        return OperateResult.CreateSuccessResult(str + (Convert.ToInt32(address.Substring(1)) + 1536).ToString());
                    }
                    if (address.StartsWith("C") || address.StartsWith("c"))
                    {
                        return OperateResult.CreateSuccessResult(str + (Convert.ToInt32(address.Substring(1)) + 3584).ToString());
                    }
                    if (address.StartsWith("M") || address.StartsWith("m"))
                    {
                        int num = Convert.ToInt32(address.Substring(1));
                        if (num >= 1536)
                        {
                            return OperateResult.CreateSuccessResult(str + (num - 1536 + 45056).ToString());
                        }
                        return OperateResult.CreateSuccessResult(str + (num + 2048).ToString());
                    }
                }
                else
                {
                    if (address.StartsWith("D") || address.StartsWith("d"))
                    {
                        int num2 = Convert.ToInt32(address.Substring(1));
                        if (num2 >= 4096)
                        {
                            return OperateResult.CreateSuccessResult(str + (num2 - 4096 + 36864).ToString());
                        }
                        return OperateResult.CreateSuccessResult(str + (num2 + 4096).ToString());
                    }
                    if (address.StartsWith("C") || address.StartsWith("c"))
                    {
                        int num3 = Convert.ToInt32(address.Substring(1));
                        if (num3 >= 200)
                        {
                            return OperateResult.CreateSuccessResult(str + (num3 - 200 + 3784).ToString());
                        }
                        return OperateResult.CreateSuccessResult(str + (num3 + 3584).ToString());
                    }
                    if (address.StartsWith("T") || address.StartsWith("t"))
                    {
                        return OperateResult.CreateSuccessResult(str + (Convert.ToInt32(address.Substring(1)) + 1536).ToString());
                    }
                }
                return new OperateResult<string>(StringResources.Language.NotSupportedDataType);
            }
            catch (Exception ex)
            {
                return new OperateResult<string>(ex.Message);
            }
        }

        public static OperateResult<bool[]> ReadBool(Func<string, ushort, OperateResult<bool[]>> readBoolFunc, string address, ushort length)
        {
            string str = string.Empty;
            OperateResult<int> operateResult = HslHelper.ExtractParameter(ref address, "s");
            if (operateResult.IsSuccess)
            {
                str = String.Format("s={0};", operateResult.Content);
            }
            int result = 0;
            if (address.StartsWith("M") && int.TryParse(address.Substring(1), out result) && result < 1536 && result + length > 1536)
            {
                ushort num = (ushort)(1536 - result);
                ushort arg = (ushort)(length - num);
                OperateResult<bool[]> operateResult2 = readBoolFunc(address, num);
                if (!operateResult2.IsSuccess)
                {
                    return operateResult2;
                }
                OperateResult<bool[]> operateResult3 = readBoolFunc(str + "M1536", arg);
                if (!operateResult3.IsSuccess)
                {
                    return operateResult3;
                }
                return OperateResult.CreateSuccessResult(SoftBasic.SpliceArray<bool>(operateResult2.Content, operateResult3.Content));
            }
            return readBoolFunc(address, length);
        }

        public static OperateResult Write(Func<string, bool[], OperateResult> writeBoolFunc, string address, bool[] value)
        {
            string str = string.Empty;
            OperateResult<int> operateResult = HslHelper.ExtractParameter(ref address, "s");
            if (operateResult.IsSuccess)
            {
                str = String.Format("s={0};", operateResult.Content);
            }
            int result = 0;
            if (address.StartsWith("M") && int.TryParse(address.Substring(1), out result) && result < 1536 && result + value.Length > 1536)
            {
                ushort length = (ushort)(1536 - result);
                OperateResult operateResult2 = writeBoolFunc(address, value.SelectBegin(length));
                if (!operateResult2.IsSuccess)
                {
                    return operateResult2;
                }
                OperateResult operateResult3 = writeBoolFunc(str + "M1536", value.RemoveBegin(length));
                if (!operateResult3.IsSuccess)
                {
                    return operateResult3;
                }
                return OperateResult.CreateSuccessResult();
            }
            return writeBoolFunc(address, value);
        }

        public static OperateResult<byte[]> Read(Func<string, ushort, OperateResult<byte[]>> readFunc, string address, ushort length)
        {
            string str = string.Empty;
            OperateResult<int> operateResult = HslHelper.ExtractParameter(ref address, "s");
            if (operateResult.IsSuccess)
            {
                str = String.Format("s={0};", operateResult.Content);
            }
            int result = 0;
            if (address.StartsWith("D") && int.TryParse(address.Substring(1), out result) && result < 4096 && result + length > 4096)
            {
                ushort num = (ushort)(4096 - result);
                ushort arg = (ushort)(length - num);
                OperateResult<byte[]> operateResult2 = readFunc(address, num);
                if (!operateResult2.IsSuccess)
                {
                    return operateResult2;
                }
                OperateResult<byte[]> operateResult3 = readFunc(str + "D4096", arg);
                if (!operateResult3.IsSuccess)
                {
                    return operateResult3;
                }
                return OperateResult.CreateSuccessResult(SoftBasic.SpliceArray<byte>(operateResult2.Content, operateResult3.Content));
            }
            return readFunc(address, length);
        }

        public static OperateResult Write(Func<string, byte[], OperateResult> writeFunc, string address, byte[] value)
        {
            string str = string.Empty;
            OperateResult<int> operateResult = HslHelper.ExtractParameter(ref address, "s");
            if (operateResult.IsSuccess)
            {
                str = String.Format("s={0};", operateResult.Content);
            }
            int result = 0;
            if (address.StartsWith("D") && int.TryParse(address.Substring(1), out result) && result < 4096 && result + value.Length / 2 > 4096)
            {
                ushort num = (ushort)(4096 - result);
                OperateResult operateResult2 = writeFunc(address, value.SelectBegin(num * 2));
                if (!operateResult2.IsSuccess)
                {
                    return operateResult2;
                }
                OperateResult operateResult3 = writeFunc(str + "D4096", value.RemoveBegin(num * 2));
                if (!operateResult3.IsSuccess)
                {
                    return operateResult3;
                }
                return OperateResult.CreateSuccessResult();
            }
            return writeFunc(address, value);
        }

        //[AsyncStateMachine(typeof(<ReadBoolAsync>d__5))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<bool[]>> ReadBoolAsync(Func<string, ushort, Task<OperateResult<bool[]>>> readBoolFunc, string address, ushort length)
        //{
        //    <ReadBoolAsync>d__5 stateMachine = new <ReadBoolAsync>d__5();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
        //    stateMachine.readBoolFunc = readBoolFunc;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__6))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult> WriteAsync(Func<string, bool[], Task<OperateResult>> writeBoolFunc, string address, bool[] value)
        //{
        //    <WriteAsync>d__6 stateMachine = new <WriteAsync>d__6();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.writeBoolFunc = writeBoolFunc;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadAsync>d__7))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<byte[]>> ReadAsync(Func<string, ushort, Task<OperateResult<byte[]>>> readFunc, string address, ushort length)
        //{
        //    <ReadAsync>d__7 stateMachine = new <ReadAsync>d__7();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte[]>>.Create();
        //    stateMachine.readFunc = readFunc;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__8))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult> WriteAsync(Func<string, byte[], Task<OperateResult>> writeFunc, string address, byte[] value)
        //{
        //    <WriteAsync>d__8 stateMachine = new <WriteAsync>d__8();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.writeFunc = writeFunc;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}
    }
}
